package com.my.zl.console.service.autocode.impl;

import java.time.Instant;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.my.zl.common.dto.ReqDTO;
import com.my.zl.common.dto.advancedQuery.PageQueryDTO;
import com.my.zl.common.enums.resp.GlobalEnum;
import com.my.zl.common.exception.BizException;
import com.my.zl.common.utils.CopyUtil;
import com.my.zl.console.common.config.MyselfProperties;
import com.my.zl.console.common.constant.AutocodeC;
import com.my.zl.console.common.constant.AutocodeRespE;
import com.my.zl.console.dao.autocode.ZlProjectMapper;
import com.my.zl.console.dao.autocode.ZlProjectModuleMapper;
import com.my.zl.console.dto.autocode.project.ReqProjectAddDTO;
import com.my.zl.console.dto.autocode.project.ReqProjectDelDTO;
import com.my.zl.console.dto.autocode.project.ReqProjectDetailDTO;
import com.my.zl.console.dto.autocode.project.ReqProjectEditDTO;
import com.my.zl.console.dto.autocode.project.ReqProjectQueryDTO;
import com.my.zl.console.dto.autocode.project.ReqProjectStateDTO;
import com.my.zl.console.dto.autocode.project.ResProjectAddDTO;
import com.my.zl.console.dto.autocode.project.ResProjectDelDTO;
import com.my.zl.console.dto.autocode.project.ResProjectDetailDTO;
import com.my.zl.console.dto.autocode.project.ResProjectEditDTO;
import com.my.zl.console.dto.autocode.project.ResProjectQueryDTO;
import com.my.zl.console.dto.autocode.project.ResProjectStateDTO;
import com.my.zl.console.dto.autocode.project.ResProjectVO2;
import com.my.zl.console.entity.autocode.ZlProject;
import com.my.zl.console.po.autocode.project.ZlProjectVo;
import com.my.zl.console.service.autocode.IProjectService;
import com.my.zl.console.service.base.BaseManager;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;

/**
 * 项目配置
 * @author ZL
 */
@Service
public class ProjectServiceImpl extends BaseManager implements IProjectService {

    @Autowired
    private ZlProjectMapper projectMapper;
    @Autowired
    private ZlProjectModuleMapper projectModuleMapper;
    @Autowired
    private MyselfProperties myselfProperties;
    @Autowired
    protected DataSource dynamicDataSource;
    
    @Override
    public ResProjectQueryDTO queryProjectList(ReqProjectQueryDTO reqInfo,PageQueryDTO page) throws Exception{
        // TODO Auto-generated method stub
        ResProjectQueryDTO resDTO = BeanUtil.copyProperties(page, ResProjectQueryDTO.class);
        if(StringUtils.isNotBlank(reqInfo.getProjectTitle())){
            reqInfo.setProjectTitle("%"+reqInfo.getProjectTitle()+"%");
        }
        Map<String,Object> paramMap = new HashMap<>();
        paramMap = BeanUtil.beanToMap(reqInfo);
        
        pageHandle(page);//处理分页数据
        //当效率不行时自行计数，或完全自行分页，先查询总数，如果为0不用再次查询了；开启计数：true是,false否
        //临近第一条SQL查询语句自动分页,如果未消费时(即后面没有触发SQL查询)则需主动调用pageHp.clear()清理
        Page<Object> pageHp = PageHelper.startPage(page.getPage(), page.getLimit(),page.getSortorder());
        List<ZlProjectVo> list = projectMapper.selectListPage(paramMap);
        resDTO.setData(CopyUtil.copyList(list, ResProjectVO2.class));
        resDTO.setCount(pageHp.getTotal());
        
        return resDTO;
    }
    
    @Override
    public ResProjectDetailDTO queryProjectDetail(ReqProjectDetailDTO reqInfo) throws Exception{
        // TODO Auto-generated method stub
        ResProjectDetailDTO res = new ResProjectDetailDTO();
        
        Map<String,Object> paramMap = new HashMap<>();
        paramMap = BeanUtil.beanToMap(reqInfo);
        ZlProject view = projectMapper.selectOneByMap(paramMap);
        BeanUtil.copyProperties(view, res);
        return res;
    }
    
    @Override
    public ResProjectAddDTO insertProjectInfo(ReqDTO<ReqProjectAddDTO> reqInfo) throws Exception{
        // TODO Auto-generated method stub
        ReqProjectAddDTO reqData = reqInfo.getReqData();
        ResProjectAddDTO res = new ResProjectAddDTO();
        Instant time = getSystemTime().getUtcTime();
        
        ZlProject record = new ZlProject();
        BeanUtil.copyProperties(reqData, record);
        
        initCreateInfo(record, reqInfo, time);
        record.setProjectId(IdUtil.fastSimpleUUID());
        record.setDataStatus(AutocodeC.DataStatus.ENABLE.getCode());//状态
        record.setSqlPath(filePath(myselfProperties.getAutocodePathRoot(),myselfProperties.getAutocodePathMajor(),myselfProperties.getAutocodePathProject()
                ,new String[]{record.getProjectId().toString()+"---10","sql"}));
        record.setPdmPath(filePath(myselfProperties.getAutocodePathRoot(),myselfProperties.getAutocodePathMajor(),myselfProperties.getAutocodePathProject()
                ,new String[]{record.getProjectId().toString()+"---10","pdm"}));
        
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("projectId",record.getProjectId());
        //检查主键是否冲突
        if(projectMapper.countExistKey(paramMap)>0){
            throw new BizException(GlobalEnum.DUPLICATE_PRIMARY_KEY);
        }
        
        projectMapper.insertSelective(record);
        
        ZlProject keyInfo = projectMapper.selectOneByMap(paramMap);
        BeanUtil.copyProperties(keyInfo, res);
        
        return res;
    }
    
    @Override
    public ResProjectEditDTO updateProjectInfo(ReqDTO<ReqProjectEditDTO> reqInfo) throws Exception{
        // TODO Auto-generated method stub
        ReqProjectEditDTO reqData = reqInfo.getReqData();
        ResProjectEditDTO res = new ResProjectEditDTO();
        Instant time = getSystemTime().getUtcTime();
        
        ZlProject record = new ZlProject();
        BeanUtil.copyProperties(reqData, record);
        
        initUpdateInfo(record, reqInfo, time);
        
        projectMapper.updateByPrimaryKeySelective(record);
        
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("projectId",record.getProjectId());
        ZlProject keyInfo = projectMapper.selectOneByMap(paramMap);
        BeanUtil.copyProperties(keyInfo, res);
        
        String cdskey = "dynamic-" + record.getProjectId().toString();
        DynamicRoutingDataSource dynamicRoutingDataSource = (DynamicRoutingDataSource)dynamicDataSource;
        if(dynamicRoutingDataSource.getCurrentDataSources().containsKey(cdskey)){
            dynamicRoutingDataSource.removeDataSource(cdskey);
        }
        
        return res;
    }
    
    @Override
    public ResProjectDelDTO deleteProjectInfo(ReqDTO<ReqProjectDelDTO> reqInfo) throws Exception{
        // TODO Auto-generated method stub
        ReqProjectDelDTO reqData = reqInfo.getReqData();
        ResProjectDelDTO res = new ResProjectDelDTO();
        Instant time = getSystemTime().getUtcTime();
        
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("projectId",reqData.getProjectId());
        if(projectModuleMapper.countExistKey(paramMap) > 0){
            throw new BizException(AutocodeRespE.DELETE_NOT_ALLOWED);
        }
        ZlProject keyInfo = projectMapper.selectOneByMap(paramMap);
        
        paramMap = BeanUtil.beanToMap(reqData);
        projectMapper.deleteByMap(paramMap);
        
        String cdskey = "dynamic-" + keyInfo.getProjectId().toString();
        DynamicRoutingDataSource dynamicRoutingDataSource = (DynamicRoutingDataSource)dynamicDataSource;
        if(dynamicRoutingDataSource.getCurrentDataSources().containsKey(cdskey)){
            dynamicRoutingDataSource.removeDataSource(cdskey);
        }
        
        return res;
    }
    
    @Override
    public ResProjectStateDTO updateProjectState(ReqDTO<ReqProjectStateDTO> reqInfo) throws Exception{
        // TODO Auto-generated method stub
        ReqProjectStateDTO reqData = reqInfo.getReqData();
        ResProjectStateDTO res = new ResProjectStateDTO();
        Instant time = getSystemTime().getUtcTime();
         
        ZlProject record = new ZlProject();
        BeanUtil.copyProperties(reqData, record);
        initUpdateInfo(record, reqInfo, time);
        projectMapper.updateByPrimaryKeySelective(record);
         
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("projectId",record.getProjectId());
        ZlProject keyInfo = projectMapper.selectOneByMap(paramMap);
        BeanUtil.copyProperties(keyInfo, res);
        
        return res;
    }
}